package com.vue.controller;

import com.vue.entity.vo.SseEmitterUTF8;
import com.vue.util.SseEmitterUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * sse的测试
 * 应用场景：1，实现即时通讯；2，动态数据展示；3，单页面应用的数据刷新
 * 优势：有效的宽带利用：长链接；再网络中断时自动重连
 *
 *劣势：只能单向通信
 *
 * @author wrj
 * @since 2025/1/6 下午2:54
 */
@Slf4j
@RestController
@EnableScheduling
@RequestMapping("/sse")
public class SseController {


    private int count_down_sec = 2 * 60 * 60;

    private final ConcurrentMap<String, SseEmitter> emitters = new ConcurrentHashMap<>();


    /**
     * 用于创建连接
     */
    @GetMapping("/connect/{userId}")
    public SseEmitterUTF8 connect(@PathVariable String userId) {
        log.info("sse建立连接，用户：{}", userId);
        SseEmitterUTF8 emitter = new SseEmitterUTF8(0L);
        try {
            emitter = SseEmitterUtil.connect(userId);
        } catch (IOException e) {
            e.printStackTrace();
            SseEmitterUtil.removeUser(userId);
        }
        return emitter;
    }

    /**
     * 关闭连接
     */
    @GetMapping("/close/{userId}")
    public void close(@PathVariable("userId") String userId) {
        log.info("sse断开连接，用户：{}", userId);
        SseEmitterUtil.removeUser(userId);
    }

    /**
     * 每秒执行一次
     *
     */
//    @Scheduled(fixedDelay = 1000)
    public void sendMessage() {
        log.info("使用定时模拟消息创建：{}", System.currentTimeMillis());
        // 获取要发送的消息
        String message = getCountDownSec();
        // 给指定用户发消息
        SseEmitterUtil.sendMessage("111", message);
    }

    private String getCountDownSec() {
        if (count_down_sec > 0) {
            int h = count_down_sec / (60 * 60);
            int m = (count_down_sec % (60 * 60)) / 60;
            int s = (count_down_sec % (60 * 60)) % 60;
            count_down_sec--;
            return "活动倒计时：" + h + " 小时 " + m + " 分钟 " + s + " 秒";
        }
        return "活动倒计时：0 小时 0 分钟 0 秒";

    }


    @GetMapping(value = "/sse/{userId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamEvents(@PathVariable("userId") String userId) {
        SseEmitter emitter = new SseEmitter(0L);
        emitters.put(userId, emitter);

        // 这里不立即发送消息，而是依赖定时任务来发送
        return emitter;
    }

//    @Scheduled(fixedRate = 5000) // 每5秒执行一次
    public void sendScheduledMessages() {
        String message = "This is a scheduled message";
        emitters.values().forEach(emitter -> {
            try {
                emitter.send(SseEmitter.event().data(message));
            } catch (IOException e) {
                // 处理发送失败的情况，比如连接已经关闭
                emitter.completeWithError(e);
            }
        });
    }



}
